#include "scheduler.h"

// 全局变量，用于存储任务数量
uint8_t task_num;

// 全局变量，用于各任务间数据交换
int g_encoder_left = 0, g_encoder_right = 0;  // 编码器读数
int g_motor1_pwm = 0, g_motor2_pwm = 0;       // 电机PWM输出
uint8_t g_system_enable = 1;                  // 系统使能标志

typedef struct
{
    void (*task_func)(void);
    uint32_t rate_ms;
    uint32_t last_run;
} task_t;

// 静态任务数组，每个任务包含任务函数、执行周期（毫秒）和上次运行时间（毫秒）
static task_t scheduler_task[] =
{
    //{encoder_task, 10, 0},      // 编码器测速任务，10ms周期
    {uart_proc, 5, 0},          // 串口处理任务，5ms周期（优先处理蓝牙数据）
    {bluetooth_control_task, 10, 0}, // 蓝牙控制任务，10ms周期
    {bluetooth_task, 20, 0},    // 蓝牙状态监控任务，20ms周期
    {debug_info_task, 1000, 0}  // 调试信息任务，1000ms周期
};

/**
 * @brief 调度器初始化函数
 * 计算任务数组的元素个数，并将结果存储在 task_num 中
 */
void scheduler_init(void)
{
    // 计算任务数组的元素个数，并将结果存储在 task_num 中
    task_num = sizeof(scheduler_task) / sizeof(task_t);
    
    // 初始化串口配置
    uart_config_init();
    
    // 初始化全局变量
    g_encoder_left = g_encoder_right = 0;
    g_motor1_pwm = g_motor2_pwm = 0;
    g_system_enable = 1;
    
    // 初始化蓝牙控制变量
    Fore = Back = Left = Right = 0;
    
    // 发送启动信息
    extern UART_HandleTypeDef huart1;
    HAL_Delay(100);  // 等待串口稳定
    
    // 简化启动信息
    my_printf(&huart1, "\n=== Direct PWM Control System ===\n");
    my_printf(&huart1, "System Ready - Direct PWM control without PID\n");
    my_printf(&huart1, "Commands: F/L/R/S, speed1/2/3, status, encoder, pwm\n\n");
}

/**
 * @brief 编码器测速任务
 * 读取左右编码器的速度值
 */
//void encoder_task(void)
//{
//    extern TIM_HandleTypeDef htim3, htim4;
//    
//    // 读取左右编码器速度
//    g_encoder_left = Read_Speed(&htim3);
//    g_encoder_right = -Read_Speed(&htim4);  // 右编码器取反
//}

/**
 * @brief 蓝牙控制任务
 * 专门处理蓝牙控制逻辑，替代PID控制
 */
void bluetooth_control_task(void)
{
    if (!g_system_enable) {
        g_motor1_pwm = 0;
        g_motor2_pwm = 0;
        Load(0, 0);  // 停止电机
        return;
    }
    
    // 调用蓝牙控制函数
    Tricycle_Control();
}

/**
 * @brief 蓝牙控制任务
 * 处理蓝牙遥控指令状态监控
 */
void bluetooth_task(void)
{
    // 简化版本：不输出定期状态信息，专注于PID调试数据
    // 蓝牙指令处理正常，但不输出冗余的状态信息
}

/**
 * @brief 调试信息任务
 * 简化的系统状态信息（降低输出频率）
 */
void debug_info_task(void)
{
    // 暂时禁用详细的系统状态输出，专注于PID调试
    // 如果需要系统状态，可以通过蓝牙发送"status"指令查看
}

/**
 * @brief 调度器运行函数
 * 遍历任务数组，检查是否有任务需要执行。如果当前时间已经超过任务的执行周期，则执行该任务并更新上次运行时间
 */
void scheduler_run(void)
{
    // 遍历任务数组中的所有任务
    for (uint8_t i = 0; i < task_num; i++)
    {
        // 获取当前的系统时间（毫秒）
        uint32_t now_time = HAL_GetTick();

        // 检查当前时间是否达到任务的执行时间
        if (now_time >= scheduler_task[i].rate_ms + scheduler_task[i].last_run)
        {
            // 更新任务的上次运行时间为当前时间
            scheduler_task[i].last_run = now_time;

            // 执行任务函数
            scheduler_task[i].task_func();
        }
    }
}
